package com.yuneec.droneservice.command;

import android.os.RemoteException;

import com.yuneec.droneservice.request.IResponseHandler;
import com.yuneec.droneservice.request.OnRequestListener;
import com.yuneec.rcdronesercive.RCIRH;
import com.yuneec.rcdronesercive.RCProtocolPlugin;
import com.yuneec.droneservice.request.IRequest;
import com.yuneec.droneservice.request.IResponse;
import com.yuneec.droneservice.utils.ByteUtils;
import com.yuneec.droneservice.utils.CrcUtils;


/**
 * This is abstract class of command,provider default methods about command,command ID,command type.
 *
 * @author jw.gu
 * @version 1.0
 */
public abstract class BaseCommand extends IRequest {
    public static final byte COMMAND_SENDERID = 0x31;//0x18
    public static final byte RESPONSE_SENDERID = 0x13;//0x81
    public static final byte RESPONSE_RADIO = 0x15;//0x81
    public static final byte HANDERID = 0x40;

    protected byte[] data;//payload中不包含commandID的部分

    protected BaseCommand(int id) {
        super(id);
    }

    /**
     * Is there a reply after post command
     *
     * @return true if has a reply
     * @throws RemoteException
     */
    @Override
    public boolean hasReply() {
        return true;
    }

    public byte getSenderId() {
        return COMMAND_SENDERID;
    }

    public byte[] toRawData() {
        byte[] raw;
        short len;
        if (data == null || data.length == 0) {
            raw = new byte[6];
            len = 2;
        } else {
            raw = new byte[6 + data.length];
            len = (short) (data.length + 2);
            System.arraycopy(data, 0, raw, 5, data.length);
        }
        raw[0] = HANDERID;
        raw[1] = getSenderId();
        ByteUtils.shortToByteArray(raw, 2, len, IS_BIGENDIAN);
        raw[4] = (byte) (ids() & 0xff);
        raw[raw.length - 1] = CrcUtils.crc8Table(raw, 0, raw.length - 1);
        return raw;
    }

    @Override
    public boolean parseReply(IResponseHandler irh, OnRequestListener listener) {
        RCIRH rcirm = RCIRH.class.cast(irh);
        rcirm.handle();
        IResponse<?> response = toResponse(rcirm.data, rcirm.offset, rcirm.length);
        rcirm.initResponseHandler(response, listener);
        return hasReply();
    }

    public abstract IResponse toResponse(byte[] data, int payloadOff, int payloadLen);

    @Override
    public int port() {
        return RCProtocolPlugin.BASE_COMMAND_MSG_ID;
    }
}
